package com.my.chapter15;


public class practice28 {
    static <T> void f1(Generic1<? super T> obj, T item) {
        obj.set(item);
    }
    static <T> T f2(Generic2<? extends T> obj) {
        return obj.get();
    }

    public static void main(String[] args) {
        Generic1<Rodent> g1 = new Generic1<Rodent>();
        f1(g1,new Mouse());
        // Compile error: Cats is not a Rodent
        // f1(g1, new Cats());
        Generic2<Pets> g2 = new Generic2<Pets>();
        Pets pet = f2(g2);
        Generic2<Cats> g3 = new Generic2<Cats>();
        Cats cat = f2(g3); // OK
        pet = f2(g3); // OK
    }
}

class Generic1<T> {
    public void set(T arg) {}
}
class Generic2<T> {
    public T get() { return null; }
}


class Pets{

    @Override
    public String toString() {
        return "Pet";
    }
}

class Dogs extends Pets {

    @Override
    public String toString() {
        return "Dog";
    }
}

class Mutt extends Dogs {

    @Override
    public String toString() {
        return "Mutt";
    }
}

class Pug extends Dogs {

    @Override
    public String toString() {
        return "Pug";
    }
}

class Cats extends Pets {

    @Override
    public String toString() {
        return "Cat";
    }
}

class EgyptianMau extends Pets {

    @Override
    public String toString() {
        return "EgyptianMau";
    }
}

class Manx extends Pets {

    @Override
    public String toString() {
        return "Manx";
    }
}

class Cymric extends Manx {

    @Override
    public String toString() {
        return "Cymric";
    }
}

class Rodent extends Pets {

    @Override
    public String toString() {
        return "Rodent";
    }
}

class Rat extends Rodent {

    @Override
    public String toString() {
        return "Rat";
    }
}

class Mouse extends Rodent {

    @Override
    public String toString() {
        return "Mouse";
    }
}

class Hamster extends Rodent {

    @Override
    public String toString() {
        return "Mouse";
    }
}